#define MM_TIME_VOTE_INCLUDED 1

#if !defined MM_GLOBALS_INCLUDED
#include "include/mm_globals.inl"
#endif

#define TASK_MAP_TIME_VOTE 100

#define MAX_MAP_TIMES 5


new gCvarTimeVote;
new gCvarTimeVoteRound;
new gCvarTimeVoteTimes;
new gCvarTimeVoteDelay;
new gCvarTimeVoteTime;
new gCvarTimeVoteWin;
new gCvarTimeVoteWinPercent;
new gCvarTimeVoteResults;

new gTIME_VOTE_MENU;
new mapTimeVoteEnd;

new mapTimesCount;
new mapTimes[MAX_MAP_TIMES];
new mapTimesVotes[MAX_MAP_TIMES];
new playerVotedForMapTime[33];
new timeVoteShown;
new isTimeSecondVote;
new isTimeMenuVisible;
new gRound;

stock  client_connect_timeVote(id) {
	playerVotedForMapTime[id] = PLAYER_DID_NOT_VOTE;
	if(isTimeMenuVisible)
		menu_display(id, gTIME_VOTE_MENU);
}

stock client_disconnect_timeVote(id){
	if(isTimeMenuVisible){
		new t = playerVotedForMapTime[id];
		if(t < PLAYER_DID_NOT_VOTE){
			mapTimesVotes[t] --;
		}
	}
}

stock roundStart_timeVote(){
	gRound++;
	if(timeVoteShown)
		return;
	if(gRound == get_pcvar_num( gCvarTimeVoteRound) && get_pcvar_num(gCvarTimeVote)){
		showFirstDelayedMapTimeVote();
	}
}

stock plugin_init_timeVote() {
	gCvarTimeVote = register_cvar("mm_time_vote", "1");
	gCvarTimeVoteRound = register_cvar("mm_time_vote_round", "3");
	gCvarTimeVoteTimes = register_cvar("mm_times" ,"10 15 20 25 30") ;
	gCvarTimeVoteDelay = register_cvar("mm_time_vote_delay", "15");
	gCvarTimeVoteTime = register_cvar("mm_time_vote_time", "20");
	gCvarTimeVoteWin = register_cvar("mm_time_vote_win", "0");
	gCvarTimeVoteWinPercent = register_cvar("mm_time_vote_win_percent", "50");
	gCvarTimeVoteResults = register_cvar("mm_time_vote_results" , "1");
}

//{ Main Time Vote Menu
public showFirstDelayedMapTimeVote() {
	timeVoteShown = 1;
	getFirstVoteTimes();
	createMenu();
	new delay = get_pcvar_num(gCvarTimeVoteDelay);
	if (delay > 5)
		set_task(float(delay -5), "speakTimeToChoose", 5);
	else 
		speakTimeToChoose(delay);
	set_task(float(delay), "mapTimeVote", TASK_MAP_TIME_VOTE);
	set_hudmessage(0, 0, 255, -1.0, 0.35, 0, 6.0, 5.0);
	ShowSyncHudMsg(0, gHudCenteredMsg, "%L", LANG_PLAYER, "VOTING_FOR_TIME", delay);
}

stock getFirstVoteTimes(){
	new times[64];
	new t1[3];
	new t;
	get_pcvar_string(gCvarTimeVoteTimes, times, charsmax(times));
	while(times[0]  && mapTimesCount< MAX_MAP_TIMES){
		strbreak(times, t1, charsmax(t1), times, charsmax(times));
		t = str_to_num(t1);
		if(t){
			mapTimes[mapTimesCount] = t;			
			mapTimesCount++;
		}
	}
}


//} Main Time Vote Menu
//{ Second Time Vote Menu
public showSecondDelayedMapTimeVote() {
	for(new i=0;i<MAX_PLAYERS;i++){
		playerVotedForMapTime[i] = PLAYER_DID_NOT_VOTE;
	}
	getSecondVoteTimes();
	createMenu();
	set_task(5.0, "speakTimeToChoose", 5);
	set_task(10.0, "mapTimeVote", TASK_MAP_TIME_VOTE);
	set_hudmessage(0, 0, 255, -1.0, 0.35, 0, 6.0, 5.0);
	ShowSyncHudMsg(0, gHudCenteredMsg, "%L", LANG_PLAYER, "VOTING_FAILED_NEXT_IN_TEN");
}

stock getSecondVoteTimes(){
	new itm1 = -1, itm1count=-1, idx1, idx2, itm2=-1,itm2count=-1;
	
	getTop2(mapTimes, mapTimesVotes, mapTimesCount, itm1, idx1,itm1count,itm2,idx2, itm2count);
	
	for(new i=0;i<mapTimesCount;i++) {		
		mapTimesVotes[i] = 0;
		mapTimes[i] = 0;
	}
	
	mapTimes[0] = itm1;
	mapTimes[1] = itm2;
	mapTimesCount = 2;
}
//}

stock createMenu(){
	new title[32];
	formatex(title, charsmax(title), "\r%L", LANG_PLAYER, "TITLE_TIME_VOTE");
	gTIME_VOTE_MENU = menu_create(title, "handleTimeVote");

	new t;
	new item[16];
	new itm[2];
	
	for(new i=0;i<mapTimesCount;i++){
		t = mapTimes[i];
		itm[0] = i;
		formatex(item, charsmax(item), "%d %L", t, LANG_PLAYER, "MINUTES");
		menu_additem(gTIME_VOTE_MENU, item, itm);
	}
}

public mapTimeVote(){
	mapTimeVoteEnd = 0;
	new players[32];
	new num;
	get_players(players, num, "ch");
	
	for(new i=0;i<num;i++) {
		menu_display(players[i], gTIME_VOTE_MENU);
	}
	showTimeVoteResults();
	isTimeMenuVisible = 1;
	set_task(get_pcvar_float(gCvarTimeVoteTime), "mapTimeVoteEnded");
}
public mapTimeVoteEnded(){
	mapTimeVoteEnd = 1;
	new players[32];
	new num;
	get_players(players, num);
			
	isTimeMenuVisible =  0;
	new mp_timelimit = 0;
	new setOrg = 0;
	if(isTimeSecondVote){
		if(mapTimesVotes[1] > mapTimesVotes[0]){
			mp_timelimit = mapTimes[1];
		} else {
			mp_timelimit = mapTimes[0];
		}
	} else {
		new itm =mapTimes[0];
		new itmcount=mapTimesVotes[0];
		new sum = 0;
		new count = 0;
		sum = itm * itmcount;
		count = itmcount;
		for(new i =1;i<mapTimesCount;i++){
			sum += mapTimesVotes[i] * mapTimes[i];
			count += mapTimesVotes[i];
			if(mapTimesVotes[i]>itmcount){
				itm = mapTimes[i];
				itmcount = mapTimesVotes[i];
			}
		}
		new type = get_pcvar_num(gCvarTimeVoteWin);
		switch(type){
			case 0:
			mp_timelimit = itm;
			case 1:{
				new percent = get_pcvar_num(gCvarTimeVoteWinPercent);
				new minVotes =  floatround(float( num * percent)/100.0);
				if(itmcount>= minVotes){
					mp_timelimit = itm;
				}
			}
			case 2:{
				if(sum >0  && count > 0)
					mp_timelimit = floatround(float(sum)/ float(count));
				else
					setOrg = 1;
			}
		}
	}
	
	for(new i=0;i<num;i++)
		menu_cancel(players[i]);
	menu_destroy(gTIME_VOTE_MENU);
	
	if(setOrg){
		set_pcvar_float(gCvarMP_TIMELIMIT,  gMP_TIMELIMIT);
		set_task(getSecondsToMapEnd() -5, "changeMapInFive", TASK_MAP_CHANGE);
		client_print(0, print_chat, "%L", LANG_PLAYER, "MAP_TIME_WILL_BE", floatround(gMP_TIMELIMIT));
	} else {
		if(mp_timelimit > 0) {
			new Float:mins = float(mp_timelimit);
			
			set_pcvar_float(gCvarMP_TIMELIMIT,  mins);
			set_task(getSecondsToMapEnd() -5, "changeMapInFive", TASK_MAP_CHANGE);
			client_print(0, print_chat, "%L", LANG_PLAYER, "MAP_TIME_WILL_BE", mp_timelimit);
		} else {
			isTimeSecondVote = 1;
			showSecondDelayedMapTimeVote();
		}
	}
}

public handleTimeVote(id, menu, item) {
	if(playerVotedForMapTime[id] == PLAYER_DID_NOT_VOTE){
		if(mapTimeVoteEnd) {
			client_print(id, print_chat, "%L", LANG_PLAYER, "VOTE_END");
		}  else {
			new name[MAX_NAME_LEN];
			get_user_name(id, name, MAX_NAME_LEN -1);
			new itemId;
			new chosenTime;
			if(item != MENU_EXIT){
				new acc, callback;
				new info[2];
				menu_item_getinfo(menu, item, acc, info, 1, _, _, callback);
				
				itemId = info[0];
				playerVotedForMapTime[id] = itemId;
				chosenTime = mapTimes[itemId];
				client_print(0, print_chat, "%L", LANG_PLAYER, "MAP_TIME_CHOSEN",name,  chosenTime);
				mapTimesVotes[itemId]++ ;
			} else {
				client_print(0, print_chat, "%L", LANG_PLAYER, "PLAYER_NOT_VOTING", name);
				playerVotedForMapTime[id] = PLAYER_VOTE_EXIT;
			}
		}
		return PLUGIN_HANDLED;
	}
	return PLUGIN_CONTINUE;
}
stock showTimeVoteResultsForPlayer(id){
	new t;
	new msg[256];
	new item[32];
	new result = get_pcvar_num(gCvarTimeVoteResults);
	if(get_pcvar_num(gCvarTimeVoteWin) != 2 && result == 3)
		result = 1;
	switch(result){
		case 0: return;
		case 1:{
			for(new i=0;i<mapTimesCount;i++){
				t = mapTimes[i];
				formatex(item, charsmax(item), "%d %L [%d]^n", t, id, "MINUTES", mapTimesVotes[i]);
				add(msg, charsmax(msg), item);
			}
		}
		case 2: {
			new itm1 = -1, itm1count=-1, idx1, idx2, itm2=-1,itm2count=-1;
			getTop2(mapTimes, mapTimesVotes, mapTimesCount, itm1, idx1,itm1count,itm2,idx2, itm2count);
	
			formatex(item, charsmax(item), "%d %L [%d]^n", itm1, id, "MINUTES", itm1count);
			add(msg, charsmax(msg), item);
			formatex(item, charsmax(item), "%d %L [%d]", itm2, id, "MINUTES", itm2count);
			add(msg, charsmax(msg), item);
		}
		case 3:{
			new sum = 0;
			for(new i =1;i<mapTimesCount;i++){
				sum += mapTimesVotes[i] * mapTimes[i];
			}
			new num = getRealPlayersnum();
			formatex(msg, charsmax(msg), "%d %L", floatround(float(sum)/ float(num)),  id, "MINUTES");
		}
	}
	trim(msg);
	set_hudmessage(255, 0, 0, 0.01, 0.14, 0, 6.0, 0.5);
	ShowSyncHudMsg(id, gHudCenteredMsg,  msg);
}
public showTimeVoteResults() {
	new players[32];
	new num;
	get_players(players,num, "ch");
	for(new i=0;i<num;i++){
		showTimeVoteResultsForPlayer(players[i]);
	}
	
	if(!mapTimeVoteEnd){
		set_task(0.5, "showTimeVoteResults");
	}
}

